package com.db4o.odbgen.plugins.xmlschema;

import java.util.ArrayList;
import java.util.List;

/**
 * 
 * Handles the XmlSchema.
 * Use this to query for nodes within the schema.
 * Contains all valid XmlSchema files found within the input directory.
 * The root nodes are considered to be those nodes that are situated under <xmlschema>.
 * @author liviug
 */
public class XmlSchema {
    private List<Element> _rootElements;
    
    public XmlSchema(List<Element> rootElements){
        this._rootElements = rootElements;
    }
    
    /**
     * Returns all root elements.
     */
    public List<Element> getAllRootElements(){
        return this._rootElements;
    }

    /**
     * Returns all root elements with the given name.
     */
    public List<Element> getRootElements(String elementName){
        List<Element> res = new ArrayList<Element>();
        for(Element e : this.getAllRootElements()){
            if(e.getName().equals(elementName))
                res.add(e);
        }
        return res;
    }

    public static class SchemaUsageStatistics{
        public List<Element> notUsedElementList;
        public int totalElements;
        public int notUsedElements;
        public int usedElements;
    }
    
    /**
     * Used to generate usage statistics about the XmlSchema.
     * This method must be called only once because it alters the usage flags
     * of elements.
     * Usually it is called after all XmlSchema operations have been completed.
     */
    public SchemaUsageStatistics buildXmlSchemaUsageStatistics() {
        XmlSchema.SchemaUsageStatistics res = new SchemaUsageStatistics();
        res.notUsedElementList = new ArrayList<Element>();
        
        //Recursivaly iterate all elements and get the statistics.
        List<Element> roots = this.getAllRootElements();
        this.buildXmlSchemaUsageStatistics(roots, res);
        
        return res;
    }

    /**
     * Recursively calculates statistics.
     * @param rootElements The elements to recurse and calculate statistics for.
     * @param statistics The object that holds the statistics.
     */
    private void buildXmlSchemaUsageStatistics(List<Element> rootElements, SchemaUsageStatistics statistics) {
        for(Element elem : rootElements){
            statistics.totalElements++;
            if(elem.isUsed()){
                statistics.usedElements++;
            }
            else{
                statistics.notUsedElements++;
                statistics.notUsedElementList.add(elem);
            }
            this.buildXmlSchemaUsageStatistics(elem.getAllChildren(), statistics);
        }
    }
    
    
    /**
     * Returns a string hierarchical representation of the schema
     * used for debug purposes.
     */
    @Override
    public String toString() {
        StringBuilder res = new StringBuilder();
        for(Element e : this.getAllRootElements()){
            res.append(e.toString(0));
        }
        return res.toString();
    }
}
